package com.vcredit.creditcat.manager.mobile;

import java.util.Date;
import java.util.List;

import com.vcredit.creditcat.enumtype.PlatformTypeEnum;
import com.vcredit.creditcat.service.*;
import com.vcredit.creditcat.util.EnumExtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;
import com.fasterxml.jackson.core.type.TypeReference;
import com.vcredit.bird.enumtype.MobileCodeEnum;
import com.vcredit.bird.enumtype.MobileStatusEnum;
import com.vcredit.bird.service.base.BirdResponse;
import com.vcredit.bird.service.mobile.MobileProcessService;
import com.vcredit.creditcat.api.IMobileProcessManager;
import com.vcredit.creditcat.dto.mobile.MobileBillDetail;
import com.vcredit.creditcat.dto.mobile.MobileProcessInDto;
import com.vcredit.creditcat.dto.mobile.MobileProcessOutDto;
import com.vcredit.creditcat.dto.mobile.MobileProcessStatus;
import com.vcredit.creditcat.enumtype.AuthItemEnum;
import com.vcredit.creditcat.manager.CreditCatProcessManager;
import com.vcredit.creditcat.model.AuthItem;
import com.vcredit.creditcat.model.AuthLog;
import com.vcredit.creditcat.model.AuthMobile;
import com.vcredit.creditcat.model.CallLog;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.util.Constants;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.util.JacksonUtil;

@Service(protocol = { "protocol1" }, version = "1.0")
public class MobileProcessManager implements IMobileProcessManager {

	@Autowired
	private MobileProcessService mobileProcessService;
	@Autowired
	private AuthMobileService authMobileService;
	@Autowired
	private CustService custService;
	@Autowired
	private CreditCatProcessManager creditCatProcessManager;
	@Autowired
	private AuthLogService authLogService;
	
	@Autowired
	private CallLogService callLogService;

	@Autowired
	private CustSupplementItemService custSupplementItemService;

	private static Logger logger = LoggerFactory.getLogger(MobileProcessOutDto.class);

	@Log
	public MobileProcessOutDto mobileInit(MobileProcessInDto param, Cust cust) throws Exception {
		MobileProcessOutDto MobileProcessOutDto = new MobileProcessOutDto();
		setMobilePlatformType(param);
		BirdResponse ret = mobileProcessService.moblieInit(cust.getCustName(), param.getMobileNo(), cust.getCustIdno(),
				param.getPlatformType());
		if (ret.getVerCodeBase64() != null) {
			MobileProcessOutDto.setvCodeImage(ret.getVerCodeBase64().equals("none") ? "" : ret.getVerCodeBase64());
		} else {
			MobileProcessOutDto.setvCodeImage("");
		}
		MobileProcessOutDto.setMobileToken(ret.getToken());
		MobileProcessOutDto.setNextProCode(getNextStep(ret.getNextCode()));
		MobileProcessOutDto.setWebsite(ret.getWebsite());
		PlatformTypeEnum platformTypeEnum =
				EnumExtUtil.getEnumOnValue(PlatformTypeEnum.class,
						String.valueOf(param.getPlatformType()), "value");
		AuthMobile authMobile = new AuthMobile(cust.getLastProccessId(), param.getMobileNo(), ret.getDesc(),
				ret.getWebsite(), null,platformTypeEnum.getCode());
		MobileStatusEnum mobileStatus = ret.getNextCode().equals("Query") ? MobileStatusEnum.AUTHENTICATING
				: MobileStatusEnum.UN_AUTHENTICATE;
		authMobile.setResultStatus(mobileStatus.getCode());
		authMobile.setMobileStatus(MobileCodeEnum.INIT.getCode());
		authMobileService.updateProcess(authMobile);
		custSupplementItemService.saveOrUpdateStatus(cust,param.getAuthCode(),String.valueOf(authMobile.getMobileProcessId()),transResultStatus(authMobile.getResultStatus()),null);
		return MobileProcessOutDto;
	}

	@Log
	public MobileProcessOutDto mobileLogin(MobileProcessInDto param, Cust cust) throws Exception {
		MobileProcessOutDto MobileProcessOutDto = new MobileProcessOutDto();
		setMobilePlatformType(param);
		BirdResponse ret = mobileProcessService.mobileLogin(param.getMobileToken(), cust.getCustName(),
				param.getMobileNo(), cust.getCustIdno(), param.getServicePwd(), param.getAuthCodeImg(),
				param.getAuthCodeSMS(), param.getPlatformType(), param.getNextProCode(), param.getWebsite());
		MobileBillDetail result = null;
		if (ret.getNextCode().equals("Query")) {
			result = JacksonUtil.Json2Obj(ret.getResult(), new TypeReference<MobileBillDetail>() {
			});
		}
		if (ret.getVerCodeBase64() != null) {
			MobileProcessOutDto.setvCodeImage(ret.getVerCodeBase64().equals("none") ? "" : ret.getVerCodeBase64());
		} else {
			MobileProcessOutDto.setvCodeImage("");
		}
		MobileProcessOutDto.setMobileToken(ret.getToken());
		MobileProcessOutDto.setNextProCode(getNextStep(ret.getNextCode()));
		MobileProcessOutDto.setWebsite(ret.getWebsite());
		MobileStatusEnum mobileStatus = ret.getNextCode().equals("Query") ? MobileStatusEnum.AUTHENTICATING
				: MobileStatusEnum.UN_AUTHENTICATE;
		PlatformTypeEnum platformTypeEnum =
				EnumExtUtil.getEnumOnValue(PlatformTypeEnum.class,
						String.valueOf(param.getPlatformType()), "value");
		AuthMobile authMobile = new AuthMobile(cust.getLastProccessId(), param.getMobileNo(), ret.getDesc(),
				ret.getWebsite(), result == null ? "" : result.getId(),platformTypeEnum.getCode());
		authMobile.setResultStatus(mobileStatus.getCode());
		authMobile.setMobileStatus(Integer.valueOf(param.getNextProCode()));
		authMobileService.updateProcess(authMobile);
		custSupplementItemService.saveOrUpdateStatus(cust,param.getAuthCode(),String.valueOf(authMobile.getMobileProcessId()),transResultStatus(authMobile.getResultStatus()),null);
		return MobileProcessOutDto;
	}

	@Log
	public MobileProcessOutDto mobileSendSms(MobileProcessInDto param, Cust cust) throws Exception {
		MobileProcessOutDto MobileProcessOutDto = new MobileProcessOutDto();
		setMobilePlatformType(param);
		BirdResponse ret = mobileProcessService.mobileSendSms(param.getMobileToken(), param.getMobileNo(),
				param.getPlatformType(), param.getWebsite());
		MobileBillDetail result = null;
		if (ret.getNextCode().equals("Query")) {
			result = JacksonUtil.Json2Obj(ret.getResult(), new TypeReference<MobileBillDetail>() {
			});
		}
		MobileProcessOutDto.setNextProCode(getNextStep(ret.getNextCode()));
		if (ret.getVerCodeBase64() != null) {
			MobileProcessOutDto.setvCodeImage(ret.getVerCodeBase64().equals("none") ? "" : ret.getVerCodeBase64());
		} else {
			MobileProcessOutDto.setvCodeImage("");
		}
		MobileProcessOutDto.setWebsite(param.getWebsite());
		MobileProcessOutDto.setMobileToken(param.getMobileToken());
		PlatformTypeEnum platformTypeEnum =
				EnumExtUtil.getEnumOnValue(PlatformTypeEnum.class,
						String.valueOf(param.getPlatformType()), "value");
		AuthMobile authMobile = new AuthMobile(cust.getLastProccessId(), param.getMobileNo(), ret.getDesc(),
				param.getWebsite(), result == null ? "" : result.getId(),platformTypeEnum.getCode());
		MobileStatusEnum mobileStatus = ret.getNextCode().equals("Query") ? MobileStatusEnum.AUTHENTICATING
				: MobileStatusEnum.UN_AUTHENTICATE;
		authMobile.setResultStatus(mobileStatus.getCode());
		authMobile.setMobileStatus(Integer.valueOf(param.getNextProCode()));
		authMobileService.updateProcess(authMobile);
		custSupplementItemService.saveOrUpdateStatus(cust,param.getAuthCode(),String.valueOf(authMobile.getMobileProcessId()),transResultStatus(authMobile.getResultStatus()),null);
		return MobileProcessOutDto;
	}

	@Log
	public MobileProcessOutDto mobileCheckSms(MobileProcessInDto param, Cust cust) throws Exception {
		MobileProcessOutDto MobileProcessOutDto = new MobileProcessOutDto();
		setMobilePlatformType(param);
		BirdResponse ret = mobileProcessService.mobileCheckSms(param.getMobileToken(), param.getMobileNo(),
				param.getAuthCodeImg(), param.getAuthCodeSMS(), param.getQueryCode(), param.getPlatformType(),
				param.getNextProCode(), param.getWebsite());
		MobileBillDetail result = null;
		if (ret.getNextCode().equals("Query")) {
			result = JacksonUtil.Json2Obj(ret.getResult(), new TypeReference<MobileBillDetail>() {
			});
		}
		MobileProcessOutDto.setNextProCode(getNextStep(ret.getNextCode()));
		if (ret.getVerCodeBase64() != null) {
			MobileProcessOutDto.setvCodeImage(ret.getVerCodeBase64().equals("none") ? "" : ret.getVerCodeBase64());
		} else {
			MobileProcessOutDto.setvCodeImage("");
		}
		MobileProcessOutDto.setWebsite(param.getWebsite());
		MobileProcessOutDto.setMobileToken(param.getMobileToken());
		PlatformTypeEnum platformTypeEnum =
				EnumExtUtil.getEnumOnValue(PlatformTypeEnum.class,
						String.valueOf(param.getPlatformType()), "value");
		AuthMobile authMobile = new AuthMobile(cust.getLastProccessId(), param.getMobileNo(), ret.getDesc(),
				param.getWebsite(), result == null ? "" : result.getId(),platformTypeEnum.getCode());
		MobileStatusEnum mobileStatus = ret.getNextCode().equals("Query") ? MobileStatusEnum.AUTHENTICATING
				: MobileStatusEnum.UN_AUTHENTICATE;
		authMobile.setResultStatus(mobileStatus.getCode());
		authMobile.setMobileStatus(Integer.valueOf(param.getNextProCode()));
		authMobileService.updateProcess(authMobile);
		custSupplementItemService.saveOrUpdateStatus(cust,param.getAuthCode(),String.valueOf(authMobile.getMobileProcessId()),transResultStatus(authMobile.getResultStatus()),null);
		return MobileProcessOutDto;
	}

	public String getNextStep(String param) throws Exception {
		//logger.info("当前步骤："+ param);
		if (param.equals("Login")) {
			return "2";
		} else if (param.equals("LoginWithSMS")) {
			return "3";
		} else if (param.equals("CheckSMS")) {
			return "4";
		} else if (param.equals("SendSMSAndVercode")) {
			return "5";
		} else if (param.equals("CheckQueryCode")) {
			return "6";
		} else if (param.equals("SendSMS")) {
			return "7";
		} else if(param.equals("VerCode")){
			return "8";
		}else if(param.equals("CheckVerCode")){
			return "9";
		}else if (param.equals("Query")) {
			return "10";
		}
		return "";
	}

	public List<AuthMobile> findUnCrawl() {
		return authMobileService.findUnCrawl();
	}

	@Log
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void updateCrawlerState(AuthMobile authMobile) throws Exception {
		authMobileService.updateProcess(authMobile);
		Cust cust = custService.findById(authMobile.getCust().getCustId());
		if(authMobile.getResultStatus().equals(MobileStatusEnum.REAL_NAME.getCode())){
			cust.setCustMobile(authMobile.getMobile());
			custService.update(cust); // 更新用户手机号码
			if (authMobile.getPlatformType()==0) {
				authLogService.insert(new AuthLog(authMobile.getProcessId(), authMobile.getCust().getCustId(),
						AuthItemEnum.MOBILE.getCode(), authMobile.getExpiredTime(), new Date()));
				creditCatProcessManager.itemDone(new AuthItem(AuthItemEnum.MOBILE.getCode()),
						authMobile.getCust().getLastProccessId()); // 更新能力
			}
		}
		if(authMobile.getPlatformType()!=0){
			PlatformTypeEnum platformTypeEnum =
					EnumExtUtil.getEnumOnValue(PlatformTypeEnum.class,
							String.valueOf(authMobile.getPlatformType()), "code");
			custSupplementItemService.saveOrUpdateStatus(cust,platformTypeEnum.getAuthCode(),String.valueOf(authMobile.getMobileProcessId()),transResultStatus(authMobile.getResultStatus()),authMobile.getExpiredTime());
		}
	}

	public MobileProcessStatus getStatus(Cust cust) throws Exception {
		AuthMobile obj = authMobileService.findByProcessIdAndType(cust.getLastProccessId(),0);
		return new MobileProcessStatus(obj.getResultStatus(), obj.getRegisterName(), obj.getRegisterIdNo());
	}

	@Override
	public MobileProcessOutDto getWebSite(MobileProcessInDto param, Cust cust) throws Exception {
		MobileProcessOutDto MobileProcessOutDto = new MobileProcessOutDto();
		setMobilePlatformType(param);
		BirdResponse ret = mobileProcessService.moblieInit(cust.getCustName(), param.getMobileNo(), cust.getCustIdno(),
				param.getPlatformType());
		MobileProcessOutDto.setWebsite(ret.getWebsite());
		return MobileProcessOutDto;
	}

	/**
	 * 保存通话记录
	 * 
	 * @param callLogDto
	 * @throws Exception
	 */
	@Override
	public void saveCallRecord(List<CallLog> callLogDto) throws Exception {
		for (CallLog callLog : callLogDto) {
			callLogService.insert(callLog);
		}
	}

	/**
	 * 查询
	 * @param param
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<CallLog> findAllCallRecord(CallLog param) throws Exception {
		
		return callLogService.find(param);
	}

	private void setMobilePlatformType(MobileProcessInDto param)throws Exception{
		if(param.getAuthCode()!=null){
			PlatformTypeEnum platformTypeEnum =
					EnumExtUtil.getEnumOnValue(PlatformTypeEnum.class,
							String.valueOf(param.getAuthCode()), "authCode");
			if(platformTypeEnum!=null){
				param.setPlatformType(platformTypeEnum.getValue());
			}else{
				param.setPlatformType(Constants.PLATFORM_JXL);
			}
		}else{
			param.setPlatformType(Constants.PLATFORM_JXL);
		}
	}
	private Integer transResultStatus(Integer mobileStatus){
		switch (mobileStatus){
			case 1:
				return 0;//未认证
			case 2:
				return 2;//认证中
			case 3:
				return 3;//认证失败
			case 4:
				return 1;//认证成功
			case 5:
				return 3;//认证失败
		}
		return 3;//认证失败
	}

}
